package es.deusto.herotactics.ingameandroid;

import java.util.List;

import android.widget.Toast;

import logica.Accion;
import logica.AccionAtacar;
import logica.AccionCancelarAtaque;
import logica.AccionCancelarMovimiento;
import logica.AccionMovimiento;
import logica.AccionRangoAtaque;
import logica.AccionRangoMovimiento;
import mapa.Coordenada;
import unidades.UnidadHT;
import es.deusto.herotactics.utils.Game;
import exceptions.PlayerWonException;

/**
 * Clase que contiene la acción que se está llevando a cabo
 * 
 * @author Ibai
 *
 */
public class CurrentAction {

	private Accion action;
	private List<Coordenada> rango;
	private Coordenada currentCoord;
	private PantallaAndroid origen;
	
	public CurrentAction() {
		
	}
	
	public CurrentAction(PantallaAndroid origen, Accion action, List<Coordenada> rango, Coordenada currentCord) {
		super();
		this.action = action;
		this.rango = rango;
		this.origen = origen;
		this.currentCoord = currentCord;
		this.origen.setCurrentAction(this);
		
		if (action instanceof AccionRangoMovimiento) {
			for (Coordenada coord:rango) {
				origen.getCelda(coord).setEstado(EstadoCelda.MOVIBLE);
			}
		} else if(action instanceof AccionRangoAtaque) {
			boolean flagAtacable = false;
			UnidadHT unidad;
			for (Coordenada coord:rango) {
				unidad = (UnidadHT) origen.getPartida().getMapa().getContenidoCasilla(coord);
				if (!origen.getPartida().getTurno().getJugadorActivo().getEquipo().getUnidades().contains(unidad)) {
					origen.getCelda(coord).setEstado(EstadoCelda.ATACABLE);
					flagAtacable = true;
				}
			}
			if (!flagAtacable)
				this.cancel();
		}
	}
	
	/**
	 * Ejecuta la siguiente acción lógica a la acción actual
	 * 
	 * @param newCoord
	 */
	public void next(Coordenada newCoord) {
		if (action != null) {
			if (action instanceof AccionRangoAtaque) {
				UnidadHT unidad = (UnidadHT) origen.getPartida().getMapa().getContenidoCasilla(currentCoord);
				Celda celda = null;
				if (origen.getCelda(newCoord).getEstado() == EstadoCelda.ATACABLE && unidad != null) {
					try {
						List<Coordenada> coords = (List<Coordenada>) origen.getModeloHT().accionEnCasilla(newCoord, new AccionAtacar());
						if (coords != null) {
							celda = origen.getCelda(coords.get(AccionAtacar.UNIDAD_ATACANTE));
							celda.actualizarCelda();
							origen.getCelda(coords.get(AccionAtacar.UNIDAD_DEFENSORA)).actualizarCelda();
							resetStates();
							if (unidad != null && !unidad.puedeActuar() && celda != null)
								origen.addCeldaDesactivada(celda);
							origen.setCurrentAction(null);
							Game.actualizarPtosAccion(origen);
						} else {
							Toast.makeText(origen.getContext(), "No hay unidad a la que atacar", Toast.LENGTH_SHORT).show();
						}
					} catch (PlayerWonException e) {
						origen.jugadorGana(e.getWinner());
					}
				}
			} else if (action instanceof AccionRangoMovimiento) {
				if (origen.getCelda(newCoord).getEstado() == EstadoCelda.MOVIBLE) {
					try {
						List<Coordenada> coords = (List<Coordenada>) origen.getModeloHT().accionEnCasilla(newCoord, new AccionMovimiento());
						origen.getCelda(coords.get(AccionMovimiento.POSICION_INICIAL)).actualizarCelda();
						Celda celda = origen.getCelda(coords.get(AccionMovimiento.POSICION_FINAL));
						celda.actualizarCelda();
						resetStates();
						UnidadHT unidad = (UnidadHT) origen.getPartida().getMapa().getContenidoCasilla(newCoord);
						if (unidad != null && !unidad.puedeActuar())
							origen.addCeldaDesactivada(celda);
					Game.actualizarPtosAccion(origen);
					origen.setCurrentAction(null);
					} catch (PlayerWonException e) {
						//no hacer nada, solo puede saltar al atacar
					}
				}
			} else
				origen.setCurrentAction(null);
		}
	}
	
	/**
	 * Cancela la acción actual
	 */
	public void cancel() {
		if (action != null) {
			try {
				if (action instanceof AccionRangoAtaque) {
					origen.getModeloHT().accionEnCasilla(currentCoord, new AccionCancelarAtaque());
				} else if (action instanceof AccionRangoMovimiento) {
					origen.getModeloHT().accionEnCasilla(currentCoord, new AccionCancelarMovimiento());
				}
			} catch (PlayerWonException e) {
				//no hacer nada, solo puede saltar al atacar
			}
			resetStates();
			origen.setCurrentAction(null);
		}
	}
	
	/**
	 * Reinicia los estadoes de las celdas
	 */
	private void resetStates() {
		for (Coordenada coord : rango) {
			origen.getCelda(coord).setEstado(EstadoCelda.NORMAL);
		}
	}
}
